/**
 * Copyright (C) 2016 Eshore Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.eshore.thrpc.config.spring;

import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.thrift.TServiceClient;
import org.springframework.beans.factory.FactoryBean;

import com.eshore.thrpc.client.DefaultInvoker;
import com.eshore.thrpc.client.Invoker;
import com.eshore.thrpc.common.ServerNode;
import com.eshore.thrpc.config.ClientConfig;
import com.eshore.thrpc.heartbeat.HeartBeatManager;
import com.eshore.thrpc.proxy.DynamicClientHandler;

/**
 * 服务消费者javabean
 * <p>
 * 
 * @author : zhouzhixiang
 * @date : 2016-11-19
 */
@SuppressWarnings("rawtypes")
public class ClientBean<T> extends ClientConfig implements FactoryBean {

    /** javabean的id */
    private String id;


    /**
     * getter method
     * 
     * @see ClientBean#id
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * setter method
     * 
     * @see ClientBean#id
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }


    /**
     * 创建代理
     * <p>
     * 
     * @return {@link Object}
     */
    @SuppressWarnings("unchecked")
    public Object createProxy() throws Exception {
        check();// 参数检查
        String[] addresss = getAddress().split(":");
        ServerNode clientNode =
                new ServerNode(addresss[0], Integer.parseInt(addresss[1]), isNonBlock());

        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Class<?> objectClass = classLoader.loadClass(getIface());

        GenericKeyedObjectPool<ServerNode, TServiceClient> pool =
                buildClientPool(classLoader, objectClass);
        addShutdownHook();
        setPool(pool);

        HeartBeatManager<T> heartBeatManager =
                new HeartBeatManager<T>(getHeartbeatDelay(),
                        getHeartbeatInterval(), pool);
        heartBeatManager.setServerNode(clientNode);
        heartBeatManager.startHeatbeatTimer();

        if (getName() == null || "".equals(getName().trim())) {
            clientNode.setName(getId());
        } else {
            clientNode.setName(getName());
        }

        // return pool.borrowObject(clientNode);
        Invoker invoker = new DefaultInvoker(clientNode, pool, getRetry());
        DynamicClientHandler dynamicClientHandler = new DynamicClientHandler(invoker);
        return dynamicClientHandler.bind(classLoader, objectClass);
    }

    @Override
    public Object getObject() throws Exception {
        return createProxy();
    }

    @Override
    public Class getObjectType() {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // 加载Iface接口
        Class<?> objectClass = null;
        try {
            objectClass = classLoader.loadClass(getIface());
        } catch (ClassNotFoundException e) {}
        return objectClass;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void destory() {
        // TODO Auto-generated method stub
        super.destory();
    }
}
